package com.yohann.exam_service.utils;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * <p>
 * 有道工具
 * </p>
 *
 * @author Yohann
 * @since 2021/3/14 16:52
 */
@Slf4j
public class YoudaoUtils {

    private static final String TRANSLATION_YOUDAO_URL = "https://openapi.youdao.com/api";
    private static final String CORRECT_YOUDAO_URL = "https://openapi.youdao.com/correct_writing_text";

    private static final String TRANSLATION_APP_KEY = "647c6ced6669268d";
    private static final String CORRECT_APP_KEY = "01653a276894810f";

    private static final String TRANSLATION_APP_SECRET = "j8iKgOt2eTf13OU0ClxBa49sKjZFdcCh";
    private static final String CORRECT_APP_SECRET = "aXKF1Q5d37YTTadRlJVuC18FZxADWtAY";

    public static String translate(String q) {
        String result = "";
        Map<String, String> params = new HashMap<>();
        String salt = String.valueOf(System.currentTimeMillis());
        params.put("from", "zh-CHS");
        params.put("to", "en");
        params.put("signType", "v3");
        String curtime = String.valueOf(System.currentTimeMillis() / 1000);
        params.put("curtime", curtime);
        String signStr = TRANSLATION_APP_KEY + truncate(q) + salt + curtime + TRANSLATION_APP_SECRET;
        String sign = getDigest(signStr);
        params.put("appKey", TRANSLATION_APP_KEY);
        params.put("q", q);
        params.put("salt", salt);
        params.put("sign", sign);

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(TRANSLATION_YOUDAO_URL);
        List<NameValuePair> paramsList = new ArrayList<NameValuePair>();
        for (Map.Entry<String, String> en : params.entrySet()) {
            String key = en.getKey();
            String value = en.getValue();
            paramsList.add(new BasicNameValuePair(key, value));
        }
        CloseableHttpResponse httpResponse = null;
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(paramsList, "UTF-8"));
            httpResponse = httpClient.execute(httpPost);
            Header[] contentType = httpResponse.getHeaders("Content-Type");
            log.info("Content-Type:" + contentType[0].getValue());

            HttpEntity httpEntity = httpResponse.getEntity();
            String json = EntityUtils.toString(httpEntity, "UTF-8");
            EntityUtils.consume(httpEntity);
            log.info(json);
            Map<String, Object> map = (Map<String, Object>) JSON.parseObject(json, Map.class);
            List<String> translation = (List<String>) map.get("translation");
            if (Objects.nonNull(translation)) {
                result = translation.get(0);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (httpResponse != null) {
                    httpResponse.close();
                }
            } catch (IOException e) {
                log.info("## release resouce error ##" + e);
            }
        }

        return result;
    }

    public static Map<String, Object> correct(String str) {
        Map<String, Object> result = new HashMap<>();
        Map<String, String> params = new HashMap<>();
        String grade = "cet4";
        String salt = String.valueOf(System.currentTimeMillis());
        String curtime = String.valueOf(System.currentTimeMillis() / 1000);
        params.put("curtime", curtime);
        String signStr = CORRECT_APP_KEY + truncate(str) + salt + curtime + CORRECT_APP_SECRET;
        String sign = getDigest(signStr);
        params.put("appKey", CORRECT_APP_KEY);
        params.put("q", str);
        params.put("grade", grade);
        params.put("salt", salt);
        params.put("sign", sign);
        params.put("signType", "v3");
        CloseableHttpClient httpClient = HttpClients.createDefault();

        HttpPost httpPost = new HttpPost(CORRECT_YOUDAO_URL);
        List<NameValuePair> paramsList = new ArrayList<>();
        for (Map.Entry<String, String> en : params.entrySet()) {
            String key = en.getKey();
            String value = en.getValue();
            paramsList.add(new BasicNameValuePair(key, value));
        }
        CloseableHttpResponse httpResponse = null;
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(paramsList, "UTF-8"));
            httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            String json = EntityUtils.toString(httpEntity, "UTF-8");
            EntityUtils.consume(httpEntity);

            log.info(json);
            Map<String, Object> map = (Map<String, Object>) JSON.parseObject(json, Map.class);
            Map<String, Object> ResponseResult = (Map<String, Object>) map.get("Result");
            String essayAdvice = (String) ResponseResult.get("essayAdvice");
            String totalScore = ResponseResult.get("totalScore").toString();
            Map<String, Object> essayFeedback = (Map<String, Object>) ResponseResult.get("essayFeedback");
            List<Map<String, Object>> sentsFeedback = (List<Map<String, Object>>) essayFeedback.get("sentsFeedback");
            String sentFeedback = (String) sentsFeedback.get(0).get("sentFeedback");

            result.put("score", totalScore);
            result.put("advice", essayAdvice);
            result.put("feedback", sentFeedback);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (httpResponse != null) {
                    httpResponse.close();
                }
            } catch (IOException ignored) {
            }
        }

        return result;
    }

    /**
     * 生成加密字段
     */
    private static String getDigest(String string) {
        if (string == null) {
            return null;
        }
        char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        byte[] btInput = string.getBytes(StandardCharsets.UTF_8);
        try {
            MessageDigest mdInst = MessageDigest.getInstance("SHA-256");
            mdInst.update(btInput);
            byte[] md = mdInst.digest();
            int j = md.length;
            char[] str = new char[j * 2];
            int k = 0;
            for (byte byte0 : md) {
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
    }

    private static String truncate(String q) {
        if (q == null) {
            return null;
        }
        int len = q.length();
        return len <= 20 ? q : (q.substring(0, 10) + len + q.substring(len - 10, len));
    }


}